package com.fanqwz.kotlinmvvm.ui.activity

import android.arch.lifecycle.ViewModelStore
import android.os.Bundle
import android.support.annotation.CallSuper
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import com.fanqwz.kotlinmvvm.R
import com.fanqwz.kotlinmvvm.databinding.ActivityBaseBinding
import com.fanqwz.kotlinmvvm.databinding.AppDataBindingComponent
import com.fanqwz.kotlinmvvm.ui.compositor.ViewCompositor
import com.squareup.leakcanary.RefWatcher
import dagger.android.AndroidInjection
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasFragmentInjector
import dagger.android.support.HasSupportFragmentInjector
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import javax.inject.Inject
import kotlin.reflect.jvm.isAccessible


/**
 * Created by fanqwz on 2017/10/11.
 */


/**
 * !!!!!注意：使用DaggerAppCompactActivity会在oncreate之前注解，
 * 但是viewmodelstore是在oncreate之后加载activity，这会导致在注解
 * 中provide的viewmodel无法实现生命周期管理（每次activity销毁重建都会创建一个新的空viewmodelstore）
 *
 * 解决办法：在AndroidInjection.inject(this)之前设置viewmodelstore，
 *          并重写ViewModelStoreOwner接口*/
//@NeedPermission(permissions = [(android.Manifest.permission.READ_EXTERNAL_STORAGE), (android.Manifest.permission.WRITE_EXTERNAL_STORAGE)])
abstract class BaseActivity : AppCompatActivity(), HasFragmentInjector, HasSupportFragmentInjector {
    private val logger: Logger by lazy { LoggerFactory.getLogger(this::class.simpleName) }
    @Inject
    lateinit var supportFragmentInjector: DispatchingAndroidInjector<Fragment>
    @Inject
    lateinit var frameworkFragmentInjector: DispatchingAndroidInjector<android.app.Fragment>
    protected val rootViewCompositor: ViewCompositor by lazy {
        object : ViewCompositor() {
            lateinit var activityBaseBinding: ActivityBaseBinding
            override fun inflateView(layoutInflater: LayoutInflater): View? {
                activityBaseBinding = createView<ActivityBaseBinding>(R.layout.activity_base, null, dataBindingComponent)!!
                setSupportActionBar(activityBaseBinding.toolbar)
                return activityBaseBinding.root
            }

            override fun addView(root: ViewGroup, child: View?, compositor: ViewCompositor) {
                activityBaseBinding.baseContainer.addView(child)
            }
        }
    }
    @Inject
    lateinit var dataBindingComponent: AppDataBindingComponent
    @Inject
    lateinit var refWatcher: RefWatcher

    var myViewModelStore: ViewModelStore? = null

    @CallSuper
    open fun buildViewCompositor(): ViewCompositor {
        return rootViewCompositor
    }

    open fun onViewHierarchyBuilt() {

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        logger.trace("onCreate")
        val nc = lastNonConfigurationInstance
        if (nc != null) {
            nc::class.members.forEach {
                if (it.name == "viewModelStore") {
                    it.isAccessible = true
                    myViewModelStore = it.call(nc) as? ViewModelStore
                }
                return@forEach
            }
        }
        AndroidInjection.inject(this)

        super.onCreate(savedInstanceState)

        window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
        window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)

        buildViewCompositor()
        val root = rootViewCompositor.buildViewLayout(layoutInflater)
        setContentView(root)
        onViewHierarchyBuilt()
    }

    override fun onStart() {
        super.onStart()
        logger.trace("onStart")
    }

    override fun onResume() {
        super.onResume()
        logger.trace("onResume")
    }

    override fun onPause() {
        super.onPause()
        logger.trace("onPause")
    }

    override fun onStop() {
        super.onStop()
        logger.trace("onStop")
    }

    override fun onRestart() {
        super.onRestart()
        logger.trace("onRestart")
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
        logger.trace("onSaveInstanceState:$outState")
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        super.onRestoreInstanceState(savedInstanceState)
        logger.trace("onRestoreInstanceState:$savedInstanceState")
    }

    override fun onDestroy() {
        super.onDestroy()
        logger.trace("onDestroy")
        refWatcher.watch(this)
    }

    override fun fragmentInjector(): DispatchingAndroidInjector<android.app.Fragment>? {
        return frameworkFragmentInjector
    }

    override fun supportFragmentInjector(): DispatchingAndroidInjector<Fragment>? {
        return supportFragmentInjector
    }

    override fun getViewModelStore(): ViewModelStore {
        return myViewModelStore ?: super.getViewModelStore()
    }

//    fun setLayoutView(view: ViewCompositor) {
//        viewCompositor.addChild(view)
//    }
}